<?php
declare (strict_types = 1);

namespace app\controller\admin;

use app\event\AdminActionEvent;
use app\model\AdminActionLog;
use Symfony\Component\EventDispatcher\EventDispatcher;
use think\facade\Session;
use think\Request;
use app\model\AdminUser;
use app\traits\MyControllerTrait;
use app\validate\admin\AdminUserValidate;
use think\exception\ValidateException;
use app\model\AdminRole;

class AdminUserController
{
    use MyControllerTrait;

    protected string $uri = '/admin/user';

    public function index()
    {
        $data = [
            'uri'   => $this->uri,
            'uri2'  => "/admin/bind-role",
            'menus' => $this->getMenuNav($this->uri.'/'.__FUNCTION__),
            'title' => $this->getPermissionTitle($this->uri.'/'.__FUNCTION__)
        ];
        return view($this->uri.'/'.__FUNCTION__, $data);
    }// index() end

    public function create(Request $request)
    {
        $data = [
            'uri'       => $this->uri,
            '__token__' => $request->buildToken()
        ];
        return view($this->uri.'/'.__FUNCTION__, $data);
    }// create() end

    public function show(Request $request)
    {
        // admin_user.account
        $account = $request->get('account/s', '');

        $page  = $request->get('page/d', 1);
        $limit = $request->get('limit/d', 10);
        $where = "is_deleted = :is_deleted";
        $raw   = ['is_deleted' => 0];
        if (strlen($account) > 0)
        {
            $where         .= " AND account LIKE :account";
            $raw['account'] = "%{$account}%";
        }

        [$total, $data] = AdminUser::searchForShow(AdminUser::class, $where, $raw, $page, $limit);
        foreach ($data as $index => $adminUser){
            $data[$index]['is_lock']        = AdminUser::FIELDS['is_lock'][$adminUser['is_lock']];
            $data[$index]['admin_role_id']  = AdminRole::whereRaw("id = :id", ['id' => $adminUser['admin_role_id']])->value('title') ?? "未绑定";
            unset($data[$index]['password']);
            unset($data[$index]['salt']);
        }
        return json(['code' => 0, 'message' => 'success', 'data' => $data, 'total' => $total]);
    }// show() end

    public function store(Request $request)
    {
        $account  = $request->post('account/s', '');
        $password = $request->post('password/s', '');
        $nickname = $request->post('nickname/s', '');
        $is_lock  = $request->post('is_lock/d', 0);

        $check_data = [
            'account'   => $account,
            'password'  => $password,
            'nickname'  => $nickname,
            'is_lock'   => $is_lock
        ];
        try {
            validate(AdminUserValidate::class)->check($check_data);
        } catch (ValidateException $validateException) {
            return json(['code' => 0, 'message' => $validateException->getError()]);
        }

        $res = AdminUser::whereRaw('account = :account', ['account' => $account])->findOrEmpty();

        if ($res->isExists()) return json(['code' => 0, 'message' => '账户已存在']);

        if ($request->checkToken('__token__') === false) return json(['code' => 0, 'message' => '页面失效,请刷新页面']);

        $salt     = AdminUser::generateSalt();
        $password = AdminUser::generatePassword($password, $salt);
        AdminUser::generateLog($account, $password, $salt, $nickname, $is_lock);

        AdminActionLog::generateLog(Session::get('admin_user.id'), $request->url(), $request->ip(), "新增:{$account}");
        return json(['code' => 1, 'message' => '保存成功']);
    }// store() end

    public function edit(Request $request)
    {
        // admin_user.id
        $admin_user_id = $request->get('id/d', 0);

        $res = AdminUser::field('id, account, nickname, is_lock')->whereRaw('id = :id', ['id' => $admin_user_id])->findOrEmpty();
        if ($res->isEmpty()) return json(['code' => 0, 'message' => '用户不存在']);

        $data = [
            'uri'       => $this->uri,
            'data'      => $res->toArray(),
            '__token__' => $request->buildToken()
        ];
        return view($this->uri.'/'.__FUNCTION__, $data);
    }// edit() end

    public function edit2(Request $request)
    {
        // admin_user.id
        $admin_user_id = Session::get('admin_user.id');

        $res = AdminUser::field('id, account, nickname, is_lock')->whereRaw('id = :id', ['id' => $admin_user_id])->findOrEmpty();
        if ($res->isEmpty()) return json(['code' => 0, 'message' => '用户不存在']);

        $data = [
            'uri'       => $this->uri,
            'menus'     => $this->getMenuNav(),
            'data'      => $res->toArray(),
            '__token__' => $request->buildToken()
        ];
        return view($this->uri.'/'.__FUNCTION__, $data);
    }// edit2() end

    public function update(Request $request)
    {
        $id       = $request->put('id/d', 0);// admin_user.id
        $account  = $request->put('account/s', '');
        $password = $request->put('password/s', '');
        $nickname = $request->put('nickname/s', '');
        $is_lock  = $request->put('is_lock/d', 0);

        $check_data = [
            'account'   => $account,
            'password'  => $password,
            'nickname'  => $nickname,
            'is_lock'   => $is_lock
        ];
        try {
            validate(AdminUserValidate::class)->check($check_data);
        } catch (ValidateException $validateException) {
            return json(['code' => 0, 'message' => $validateException->getError()]);
        }

        $adminUser = AdminUser::whereRaw('id = :id', ['id' => $id])->findOrEmpty();
        if ($adminUser->isEmpty()) return json(['code' => 0, 'message' => '用户不存在']);

        // 存在里 config/super_admin.php 的管理员，无法相互编辑对方个人资料，只能是自己更新自己的资料
        if (in_array($account, config('super_admin')) &&
            in_array(Session::get('admin_user.account'), config('super_admin')) &&
            $account != Session::get('admin_user.account')
        ) return json(['code' => 0, 'message' => '超级管理员，无法相互编辑对方个人资料，只能是自己更新自己的资料']);

        // 非 config/super_admin.php 的管理员，无法编辑 config/super_admin.php 个人资料
        if (
            in_array($account, config('super_admin')) &&
            in_array(Session::get('admin_user.account'), config('super_admin')) === false
        ) return json(['code' => 0, 'message' => '无法编辑超级管理员资料']);

        if ($request->checkToken('__token__') === false) return json(['code' => 0, 'message' => '页面失效,请刷新页面']);

        if (strlen($password) > 0)
        {
            // 更新密码将同时更新 admin_user.salt
            $salt                = AdminUser::generateSalt();
            $adminUser->password = AdminUser::generatePassword($password, $salt);
            $adminUser->salt     = $salt;
        }

        $adminUser->nickname = $nickname;
        $adminUser->is_lock  = $is_lock;
        $adminUser->save();
        Session::set('admin_user.nickname', $nickname);

        $data = [
            $this->getPermissionTitle($this->uri.'/'.__FUNCTION__),
            Session::get("admin_user.account"),
            "更新管理员:{$adminUser->account}"
        ];
        (new EventDispatcher)->dispatch((new AdminActionEvent($request, $data)), AdminActionEvent::EVENT_NAME);
        return json(['code' => 1, 'message' => '保存成功']);
    }// update() end

    public function update2(Request $request)
    {
        $account  = $request->put('account/s', '');
        $password = $request->put('password/s', '');
        $nickname = $request->put('nickname/s', '');
        $is_lock  = $request->put('is_lock/d', 0);
        $id       = Session::get('admin_user.id');// admin_user.id

        $check_data = [
            'account'   => $account,
            'password'  => $password,
            'nickname'  => $nickname,
            'is_lock'   => $is_lock
        ];
        try {
            validate(AdminUserValidate::class)->check($check_data);
        } catch (ValidateException $validateException) {
            return json(['code' => 0, 'message' => $validateException->getError()]);
        }

        $adminUser = AdminUser::whereRaw('id = :id', ['id' => $id])->findOrEmpty();
        if ($adminUser->isEmpty()) return json(['code' => 0, 'message' => '用户不存在']);

        // 存在里 config/super_admin.php 的管理员，无法相互编辑对方个人资料，只能是自己更新自己的资料
        if (in_array($account, config('super_admin')) &&
            in_array(Session::get('admin_user.account'), config('super_admin')) &&
            $account != Session::get('admin_user.account')
        ) return json(['code' => 0, 'message' => '超级管理员，无法相互编辑对方个人资料，只能是自己更新自己的资料']);

        // 非 config/super_admin.php 的管理员，无法编辑 config/super_admin.php 个人资料
        if (
            in_array($account, config('super_admin')) &&
            in_array(Session::get('admin_user.account'), config('super_admin')) === false
        ) return json(['code' => 0, 'message' => '无法编辑超级管理员资料']);

        if ($request->checkToken('__token__') === false) return json(['code' => 0, 'message' => '页面失效,请刷新页面']);

        if (strlen($password) > 0)
        {
            // 更新密码将同时更新 admin_user.salt
            $salt                = AdminUser::generateSalt();
            $adminUser->password = AdminUser::generatePassword($password, $salt);
            $adminUser->salt     = $salt;
        }

        $adminUser->nickname = $nickname;
        $adminUser->is_lock  = $is_lock;
        $adminUser->save();

        $data = [
            $this->getPermissionTitle($this->uri.'/'.__FUNCTION__),
            Session::get("admin_user.account"),
            "更新管理员:{$adminUser->account}"
        ];
        (new EventDispatcher)->dispatch((new AdminActionEvent($request, $data)), AdminActionEvent::EVENT_NAME);
        return json(['code' => 1, 'message' => '保存成功']);
    }// update2() end

    public function destroy(Request $request)
    {
        $id = $request->delete('id/d');// admin_user.id

        $adminUser = AdminUser::whereRaw('id = :id', ['id' => $id])->findOrEmpty();
        if ($adminUser->isEmpty()) return json(['code' => 0, 'message' => '用户不存在']);

        // 存在里 config/super_admin.php 的管理员，无法相互删除
        if (in_array($adminUser->account, config('super_admin'))) return json(['code' => 0, 'message' => '禁止删除超级管理员']);

        if ($id == (int)session('admin_user.id')) return json(['code' => 0, 'message' => '无法删除自身']);

        $adminUser->delete();
        $data = [
            $this->getPermissionTitle($this->uri.'/'.__FUNCTION__),
            Session::get("admin_user.account"),
            "删除管理员:{$adminUser->account}"
        ];
        (new EventDispatcher)->dispatch((new AdminActionEvent($request, $data)), AdminActionEvent::EVENT_NAME);
        return json(['code'  => 1, 'message' => '删除成功']);
    }// destroy() end
}
